package proy1sistdistribuidos.control.advertisements;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import net.jxta.document.Advertisement;
import net.jxta.document.AdvertisementFactory;
import net.jxta.document.Document;
import net.jxta.document.Element;
import net.jxta.document.MimeMediaType;
import net.jxta.document.StructuredDocument;
import net.jxta.document.StructuredDocumentFactory;
import net.jxta.document.StructuredDocumentUtils;
import net.jxta.document.StructuredTextDocument;
import net.jxta.document.TextElement;
import net.jxta.id.ID;
import net.jxta.protocol.PipeAdvertisement;

/**
 * Clase AdvertisementImagen
 *
 * Clase que define un advertisement que contiene la informacion
 * asociada a una imagen
 * @author Carlos Diaz Maya, Juan Felipe Garcia
 */
public class AdvertisementImagenImpl extends AdvertisementImagen {
    private final static String mimeType= "text/xml";

    public static final String etiquetaNombreAdvertisement = "Imagen";//yap
    
    public static final String etiquetaNombreNodo = "nombreNodo";//yap
    
    public static final String etiquetaDireccionIP = "direccionIP";//yap

    public static final String etiquetafechaCreacion = "FechaCreacion";//yap

    public static final String etiquetaFechaDescarga = "FechaDescarga";//yap

    public static final String etiquetaID = "IdImagen";//yap

    public static final String etiquetaEtiquetaImagen = "Etiqueta";//yap

    public static final String etiquetaListaPersonas = "ListaPersonas";// yap

    public static final String etiquetaNombresPersona = "NombrePersona";// yap

    public static final String etiquetaApellidosPersona = "ApellidosPersona";// yap

    public static final String etiquetaAtributosEspecialesImagen = "AtributosEspeciales"; //yap

    public static final String etiquetaColorPromedio = "ColorPromedio";//yap

    public static final String etiquetaTamanho = "Tamanho";//yap

    public static final String etiquetaIdContenidoFisico = "IdContenidoFisicoB64";//yap

    public static final String etiquetaSensible = "Sensible";

    public static final String etiquetaHashArchivo = "HashArchivo";

    private PipeAdvertisement pipeAdv;

    private String nombreNodo;
    
    private String direccionIp;
    
    /**
     * arreglo de elementos para indexar el advertisement
     */
    private final static String[] camposIndexados = {etiquetaNombreAdvertisement};

    
    //Constructores
    public AdvertisementImagenImpl(InputStream stream) throws IOException, IllegalArgumentException, ParseException{
        super();

        StructuredTextDocument documentoEstructurado = (StructuredTextDocument) StructuredDocumentFactory.newStructuredDocument(new MimeMediaType(mimeType), stream);
        this.leerAdvertisement(documentoEstructurado);
    }

    public AdvertisementImagenImpl(Element documentoEstructurado) throws IllegalArgumentException, ParseException {
        super();
        this.leerAdvertisement((TextElement) documentoEstructurado);
    }

    public AdvertisementImagenImpl() {
        super();
    }
    
    //metodos
    
    private void leerAdvertisement(TextElement documentoEstructurado) throws IllegalArgumentException, ParseException{
        if(documentoEstructurado.getName().equals(getTipoAdvertisement())) {
            Enumeration elementos = documentoEstructurado.getChildren();
            while(elementos.hasMoreElements()) {
                TextElement elemento = (TextElement) elementos.nextElement();

                if(elemento.getName().equals(PipeAdvertisement.getAdvertisementType())) {
                    PipeAdvertisement pipe = (PipeAdvertisement) AdvertisementFactory.newAdvertisement(elemento);
                    setPipeAdvertisement(pipe);
                    continue;
                }
                
                if(elemento.getName().equals(etiquetaNombreAdvertisement)) {
                    this.setNombreAdvertisement(elemento.getTextValue());
                    continue;
                }
                
                if(elemento.getName().equals(etiquetaNombreNodo)) {
                    this.setNombreNodo(elemento.getTextValue());
                    continue;
                }
                
                if(elemento.getName().equals(etiquetaDireccionIP)) {
                    this.setDireccionIp(elemento.getTextValue());
                    continue;
                }
                
                if(elemento.getName().equals(etiquetafechaCreacion)) {
                    this.setFechaCreacion(elemento.getTextValue());
                    continue;
                }
                
                if(elemento.getName().equals(etiquetaFechaDescarga)) {
                    this.setFechaDescarga(elemento.getTextValue());
                    continue;
                }
                
                if(elemento.getName().equals(etiquetaID)) {
                    this.setIdImagen(elemento.getTextValue());
                    continue;
                }
                
                if(elemento.getName().equals(etiquetaEtiquetaImagen)) {
                    this.setEtiqueta(elemento.getTextValue());
                    continue;
                }
                
                if(elemento.getName().equals(etiquetaListaPersonas)) {
                    Enumeration ele = elemento.getChildren();
                    List <String[]> lista = new ArrayList<String[]>();
                    String[] parametros = new String[2];
                    while(ele.hasMoreElements()){
                        TextElement e = (TextElement) ele.nextElement();
                        
                       
                        if(e.getName().equals(etiquetaNombresPersona)) {
                            //this.setListaPersonas(elemento.getTextValue());
                            parametros[0]=e.getTextValue();
                            
                            //continue;
                        }
                        
                        if(e.getName().equals(etiquetaApellidosPersona)) {
                            parametros[1]=e.getTextValue();
                            lista.add(parametros);
                            parametros = new String[2];
                            //continue;
                        }
                        
                        
                    }
                    
                    this.setListaPersonas(lista);
                    continue;
                }
                
                if(elemento.getName().equals(etiquetaAtributosEspecialesImagen)) {
                    Enumeration ele = elemento.getChildren();
                    Long[] atributos = new Long[2];
                    while(ele.hasMoreElements()){
                        TextElement e = (TextElement) ele.nextElement();
                        
                        if(e.getName().equals(etiquetaColorPromedio)) {
                            this.setColorPromedio(e.getTextValue());
                            //atributos[0]=Long.valueOf(elemento.getTextValue());
                        }
                        
                        if(e.getName().equals(etiquetaTamanho)) {
                            String el = e.getTextValue();
                            if(el!=null){
                                this.setTamano(Long.valueOf(el));
                            } else {
                                this.setTamano(null);
                            }

                        }
                    }
                    this.setAtributosEspeciales(atributos);
                    continue;
                }
                
                if(elemento.getName().equals(etiquetaIdContenidoFisico)) {
                    this.setIdContenidoFisico(elemento.getTextValue());
                    continue;
                }

                if(elemento.getName().equals(etiquetaSensible)) {
                    this.setSensible(elemento.getTextValue()!=null?elemento.getTextValue():"false");
                    continue;
                }

                if(elemento.getName().equals(etiquetaHashArchivo)) {
                    this.setHashArchivo(elemento.getTextValue());
                    continue;
                }
            }
        }else {
            throw new IllegalArgumentException("El tipo de advertisement no tiene la estructura esperada");
        }
        
    }
    

    @Override
    public Document getDocument(MimeMediaType mmt) throws IllegalArgumentException {
               if((null!= getNombreAdvertisement()) && (null!= this.getPipeAdvertisement()))
        {
            StructuredDocument documento= (StructuredDocument) StructuredDocumentFactory.newStructuredDocument(mmt, getAdvertisementType());
            Element element;

            element= documento.createElement(etiquetaNombreAdvertisement, this.getNombreAdvertisement());
            documento.appendChild(element);
            
            element= documento.createElement(etiquetaNombreNodo, this.getNombreNodo());
            documento.appendChild(element);
            
            element= documento.createElement(etiquetaDireccionIP, this.getDireccionIp());
            documento.appendChild(element);
            
            element= documento.createElement(etiquetafechaCreacion, this.getFechaCreacion());
            documento.appendChild(element);

            //if(this.getFechaDescarga()!=null){
                element= documento.createElement(etiquetaFechaDescarga, this.getFechaDescarga());
                documento.appendChild(element);
            //}
            
            element= documento.createElement(etiquetaID, this.getIdImagen());
            documento.appendChild(element);
            
            element= documento.createElement(etiquetaEtiquetaImagen, this.getEtiqueta());
            documento.appendChild(element);
            
            element= documento.createElement(etiquetaListaPersonas);
            documento.appendChild(element);

            for(String[] elem: this.getListaPersonas()){
                Element elem2 = documento.createElement(etiquetaNombresPersona, elem[0]);
                Element elem3 = documento.createElement(etiquetaApellidosPersona, elem[1]);
                element.appendChild(elem2);
                element.appendChild(elem3);
            }
            
            
            
            element= documento.createElement(etiquetaAtributosEspecialesImagen);
            documento.appendChild(element);

            Element elem2 = documento.createElement(etiquetaColorPromedio, this.getColorPromedio());
            element.appendChild(elem2);
            Element elem3 = documento.createElement(etiquetaTamanho, this.getTamano()==null?null:this.getTamano().toString());
            element.appendChild(elem3);
            
            

            element= documento.createElement(etiquetaIdContenidoFisico, this.getIdContenidoFisico());
            documento.appendChild(element);

            element = documento.createElement(etiquetaSensible, this.getSensible());
            documento.appendChild(element);

            element = documento.createElement(etiquetaHashArchivo, this.getHashArchivo());
            documento.appendChild(element);

            PipeAdvertisement pipe = getPipeAdvertisement();
            if(pipe!=null){
                StructuredTextDocument advDoc = (StructuredTextDocument) pipe.getDocument(mmt);
                StructuredDocumentUtils.copyElements(documento, documento, advDoc);
            }
            return documento;
        }
        else{
            throw new IllegalArgumentException("faltan datos para hacer advert");
        }
    }


    @Override
    public String[] getIndexFields() {
        return this.camposIndexados;
    }

    public String toString()
    {
        try {
            StringWriter out = new StringWriter();
            StructuredTextDocument doc = (StructuredTextDocument) getDocument(new MimeMediaType(mimeType));
            doc.sendToWriter(out);
            return out.toString();
        } catch (IOException ex) {
            System.out.println("====== ERROR ======");
            System.out.println(ex.getMessage());
            return "";
        }
    }

    /**
     * @return the pipeAdv
     */
    public PipeAdvertisement getPipeAdv() {
        return pipeAdv;
    }

    /**
     * @param pipeAdv the pipeAdv to set
     */
    public void setPipeAdv(PipeAdvertisement pipeAdv) {
        this.pipeAdv = pipeAdv;
    }

    /**
     * @return the nombreNodo
     */
    public String getNombreNodo() {
        return nombreNodo;
    }

    /**
     * @param nombreNodo the nombreNodo to set
     */
    public void setNombreNodo(String nombreNodo) {
        this.nombreNodo = nombreNodo;
    }

    /**
     * @return the direccionIp
     */
    public String getDireccionIp() {
        return direccionIp;
    }

    /**
     * @param direccionIp the direccionIp to set
     */
    public void setDireccionIp(String direccionIp) {
        this.direccionIp = direccionIp;
    }

   
    public static class Instantiator implements AdvertisementFactory.Instantiator{

        public String getAdvertisementType() {
           return AdvertisementImagen.getAdvertisementType();
        }

        public Advertisement newInstance() {
            return new AdvertisementImagenImpl();
        }

        public Advertisement newInstance(Element root) {
           try{
               return new AdvertisementImagenImpl(root);
           } catch (Exception f){
               throw new RuntimeException(f);
           }
        }

    };

    

    


}
